package org.ricks.condition2;

import org.ricks.condition2.event.PlayerAwareEvent;

import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Predicate;

public class Conditions {

    // 在Conditions类中新增构建器
    public static <E extends PlayerAwareEvent, T> GenericProgressConditionBuilder<E, T> genericBuilder() {
        return new GenericProgressConditionBuilder<>();
    }

    public static class GenericProgressConditionBuilder<E extends PlayerAwareEvent, T> {
        private String playerId;
        private T initialValue;
        private T targetValue;
        private Predicate<E> eventFilter = _ -> true;
        private BiFunction<T, E, T> updateLogic;
        private Comparator<T> comparator;
        private final Set<Class<? extends E>> eventTypes = new HashSet<>();
        private Class<? extends E> eventType;
        private ComparisonOperator operator = ComparisonOperator.GREATER_OR_EQUAL;

        public GenericProgressConditionBuilder<E, T> playerId(String playerId) {
            this.playerId = playerId;
            return this;
        }
        public GenericProgressConditionBuilder<E, T> initial(T value) {
            this.initialValue = value;
            return this;
        }
        public GenericProgressConditionBuilder<E, T> target(T value) {
            this.targetValue = value;
            return this;
        }
        public GenericProgressConditionBuilder<E, T> filter(Predicate<E> filter) {
            this.eventFilter = filter;
            return this;
        }
        public GenericProgressConditionBuilder<E, T> onEvent(Class<E> eventType) {
            this.eventTypes.add(eventType);
            this.eventType = eventType;
            return this;
        }
        public GenericProgressConditionBuilder<E, T> update(BiFunction<T, E, T> logic) {
            this.updateLogic = logic;
            return this;
        }
        public GenericProgressConditionBuilder<E, T> compareWith(Comparator<T> comparator) {
            this.comparator = comparator;
            return this;
        }
        public GenericProgressConditionBuilder<E, T> operator(ComparisonOperator operator) {
            this.operator = operator;
            return this;
        }
        public GenericProgressCondition<E, T> build() {
            return new GenericProgressCondition<>(
                    playerId, initialValue, targetValue,
                    eventFilter, updateLogic, comparator,
                    eventTypes, operator, eventType
            );
        }
    }

    // 通用进度条件，支持多事件类型和自定义过滤
    // 通用进度条件（优化泛型传递）
    @SafeVarargs
    public static <T, E extends PlayerAwareEvent> Condition genericProgress(
            String playerId,
            T initialValue,
            T target,
            Predicate<E> eventFilter,
            BiFunction<T, E, T> updateLogic,
            Comparator<T> comparator,
            ComparisonOperator operator,
            Class<? extends E>... eventTypes
    ) {
        return new GenericProgressCondition<>(playerId, initialValue, target,
                eventFilter,
                updateLogic,
                comparator,
                Arrays.asList(eventTypes),
                operator, eventTypes[0]);
    }


    // 整数计数器，处理特定事件类型
    // 整数计数器（精确事件类型过滤）
    public static <E extends PlayerAwareEvent> Condition intCounter(
            String playerId,
            int initialValue,
            int target,
            Class<? extends E> eventType,
            ComparisonOperator operator
    ) {
        return genericProgress(playerId, initialValue, target,
                e -> e.getPlayerId().equals(playerId), // 自动类型推断
                (current, event) -> current + event.num(),
                Integer::compare,
                operator,
                eventType);
    }

    // 保持原有方法兼容性
    public static <E extends PlayerAwareEvent>  Condition intCounter(String playerId, int initialValue, int target,
                                       Class<? extends E> eventType) {
        return intCounter(playerId, initialValue, target, eventType, ComparisonOperator.GREATER_OR_EQUAL);
    }

    // 自定义构建器（完全类型安全）
    public static <E extends PlayerAwareEvent> Condition builder(
            String playerId,
            int initialValue,
            int target,
            BiFunction<Integer, E, Integer> updateLogic,
            Class<E> eventType
    ) {
        return new GenericProgressCondition<>(playerId, initialValue, target,
                e -> true, // 全量处理该类型事件
                updateLogic,
                Integer::compare,
                Collections.singletonList(eventType),
                ComparisonOperator.GREATER_OR_EQUAL, eventType);
    }

    /**
     * 自定义过滤
     * @param playerId
     * @param initialValue
     * @param target
     * @param eventFilter
     * @param eventType
     * @return
     */
    // 类型安全的过滤构建器
    public static <E extends PlayerAwareEvent> Condition builder(
            String playerId,
            int initialValue,
            int target,
            Predicate<E> eventFilter,
            Class<E> eventType
    ) {
        return new GenericProgressCondition<>(playerId, initialValue, target,
                eventFilter,
                (current, event) -> current + event.num(),
                Integer::compare,
                Collections.singletonList(eventType),
                ComparisonOperator.GREATER_OR_EQUAL, eventType);
    }


    // 复合条件构建器
    public static CompositeConditionBuilder composite() {
        return new CompositeConditionBuilder();
    }

    // 复合条件
    public static Condition composite(String playerId, Predicate<List<Condition>> predicate,
                                        Condition... conditions) {
        return new CompositeCondition(playerId, Arrays.asList(conditions), predicate);
    }

    public static Condition allOf(String playerId, Condition... conditions) {
        return composite(playerId, list -> list.stream().allMatch(Condition::isDone), conditions);
    }

    public static Condition anyOf(String playerId, Condition... conditions) {
        return composite(playerId, list -> list.stream().anyMatch(Condition::isDone), conditions);
    }

    // 顺序条件
    public static CompositeCondition sequence(String playerId, Condition... conditions) {
        return composite()
                .addAll(conditions)
                .completeWhen(list -> {
                    boolean foundUncompleted = false;
                    for (Condition c : list) {
                        if (foundUncompleted && c.isDone()) return false;
                        if (!c.isDone()) foundUncompleted = true;
                    }
                    return list.getLast().isDone();
                })
                .build(playerId);
    }



    // 构建器模式支持链式配置复合条件
    public static class CompositeConditionBuilder {
        private final List<Condition> children = new ArrayList<>();
        private Predicate<List<Condition>> completePredicate;

        public CompositeConditionBuilder add(Condition condition) {
            children.add(condition);
            return this;
        }

        public CompositeConditionBuilder addAll(Condition... conditions) {
            children.addAll(Arrays.asList(conditions));
            return this;
        }

        public CompositeConditionBuilder completeWhen(Predicate<List<Condition>> predicate) {
            this.completePredicate = predicate;
            return this;
        }

        public CompositeCondition build(String playerId) {
            return new CompositeCondition(playerId, children, completePredicate);
        }
    }

}



